package com.biye.api.tool.ExcelTemplate;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;

import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author Maple.Chen
 * @date 2021年2月23日
 * @description <p>邮件模板生成的工具类</p>
 */
public class PersonInfoTemplate {

    /*
     * 师生信息导入模板: 原始的下载模板方式（需要服务器程序1生成后暂存于A点，再由程序2去A点下载，当前方法相当于程序1）
     */
    @SuppressWarnings({ })
    public static int ExportExcelTemplate_XLS(String template_name,/*模板名称*/
                                              String teacher_sheet_name,/*教师模板sheet页名称*/
                                              String teacher_title,/*教师模板sheet页中首行标题*/
                                              List<String> t_column_define, /*教师模板列定义*/
                                              List<Map<String, Object>> t_list_data, /*职工数据*/
                                              Map<String, String> t_dict_map,
                                              String student_sheet_name,/*学生模板sheet页名称*/
                                              String student_title,/*学生模板sheet页中首行标题*/
                                              List<String> s_column_define, /*学生模板列定义*/
                                              List<Map<String, Object>> s_list_data, /*学生数据*/
                                              Map<String, String> s_dict_map,
                                              String export_path /*文件导出路径*/){

        // 第一步：创建一个工作簿对象
        @SuppressWarnings("resource")
        HSSFWorkbook workbook = new HSSFWorkbook();

        if(teacher_sheet_name != null){
            // 第二步：添加Sheet页
            HSSFSheet sheet = workbook.createSheet(teacher_sheet_name);

            // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制
            HSSFRow row = sheet.createRow(0);

            // 第四步，创建风格（4.1和4.2两种风格）
            // 4.1 仅文字居中
            HSSFCellStyle style = workbook.createCellStyle();
            style.setAlignment(HorizontalAlignment.CENTER);
            // 4.2 单元格边框+居中
            CellStyle style2 = workbook.createCellStyle();
            style2.setBorderBottom(BorderStyle.THIN);
            style2.setBorderLeft(BorderStyle.THIN);
            style2.setBorderRight(BorderStyle.THIN);
            style2.setBorderTop(BorderStyle.THIN);
            style2.setAlignment(HorizontalAlignment.CENTER);
            HSSFFont font = workbook.createFont();
            font.setFontHeightInPoints((short) 10); //字体高度
            font.setColor(HSSFFont.COLOR_NORMAL); //字体颜色
            font.setFontName("宋体"); //字体
            style2.setFont(font);

            // 声明列对象
            HSSFCell cell = null;

            // 五：合并单元格并设置标题   [以最左上角单元格坐标(0,0)为基准]
            CellRangeAddress callRangeAddress = new CellRangeAddress(0,0,0,t_column_define.size() - 1);//起始行,结束行,起始列,结束列
            sheet.addMergedRegion(callRangeAddress);
            cell = row.createCell(0);
            cell.setCellValue(teacher_title);
            cell.setCellStyle(style);

            // 陆：设置列名 ---- “每创建一行都需要声明sheet.createRow(rowNum)”
            row = sheet.createRow(1);
            for( int i = 0; i < t_column_define.size() ; i++ ){
                cell = row.createCell(i);
                cell.setCellValue(t_dict_map.get(t_column_define.get(i)));
                cell.setCellStyle(style2);
            }

            // 第七布：设置合并单元格的边框（合并单元格属特殊情况），上下左右都要设置
            RegionUtil.setBorderTop(BorderStyle.THIN, callRangeAddress, sheet);
            RegionUtil.setBorderBottom(BorderStyle.THIN, callRangeAddress, sheet);
            RegionUtil.setBorderLeft(BorderStyle.THIN, callRangeAddress, sheet);
            RegionUtil.setBorderRight(BorderStyle.THIN, callRangeAddress, sheet);

            // 第八步：填充数据
            for(int i = 0; i < t_list_data.size(); i++){
                row = sheet.createRow(i + 2);
                for( int j = 0; j < t_column_define.size() ; j++ ){
                    cell = row.createCell(j);
                    cell.setCellValue((String)t_list_data.get(i).get(t_column_define.get(j)));
                    cell.setCellStyle(style);
                }
            }
            // 调整列宽度
            for( int i = 0; i < t_column_define.size() ; i++ ){
                sheet.autoSizeColumn((short)i);
            }
        }
        if(student_sheet_name != null){
            // 第二步：添加Sheet页
            HSSFSheet sheet = workbook.createSheet(student_sheet_name);

            // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制
            HSSFRow row = sheet.createRow(0);

            // 第四步，创建风格（4.1和4.2两种风格）
            // 4.1 仅文字居中
            HSSFCellStyle style = workbook.createCellStyle();
            style.setAlignment(HorizontalAlignment.CENTER);
            // 4.2 单元格边框+居中
            CellStyle style2 = workbook.createCellStyle();
            style2.setBorderBottom(BorderStyle.THIN);
            style2.setBorderLeft(BorderStyle.THIN);
            style2.setBorderRight(BorderStyle.THIN);
            style2.setBorderTop(BorderStyle.THIN);
            style2.setAlignment(HorizontalAlignment.CENTER);
            HSSFFont font = workbook.createFont();
            font.setFontHeightInPoints((short) 10); //字体高度
            font.setColor(HSSFFont.COLOR_NORMAL); //字体颜色
            font.setFontName("宋体"); //字体
            style2.setFont(font);

            // 声明列对象
            HSSFCell cell = null;

            // 五：合并单元格并设置标题   [以最左上角单元格坐标(0,0)为基准]
            CellRangeAddress callRangeAddress = new CellRangeAddress(0,0,0,s_column_define.size() - 1);//起始行,结束行,起始列,结束列
            sheet.addMergedRegion(callRangeAddress);
            cell = row.createCell(0);
            cell.setCellValue(student_title);
            cell.setCellStyle(style);

            // 陆：设置列名 ---- “每创建一行都需要声明sheet.createRow(rowNum)”
            row = sheet.createRow(1);
            for( int i = 0; i < s_column_define.size() ; i++ ){
                cell = row.createCell(i);
                cell.setCellValue(s_dict_map.get(s_column_define.get(i)));
                cell.setCellStyle(style2);
            }

            // 第七布：设置合并单元格的边框（合并单元格属特殊情况），上下左右都要设置
            RegionUtil.setBorderTop(BorderStyle.THIN, callRangeAddress, sheet);
            RegionUtil.setBorderBottom(BorderStyle.THIN, callRangeAddress, sheet);
            RegionUtil.setBorderLeft(BorderStyle.THIN, callRangeAddress, sheet);
            RegionUtil.setBorderRight(BorderStyle.THIN, callRangeAddress, sheet);

            // 第八步：填充数据
            for(int i = 0; i < s_list_data.size(); i++){
                row = sheet.createRow(i + 2);
                for( int j = 0; j < s_column_define.size() ; j++ ){
                    cell = row.createCell(j);
                    cell.setCellValue((String)s_list_data.get(i).get(s_column_define.get(j)));
                    cell.setCellStyle(style);
                }
            }
            // 调整列宽度
            for( int i = 0; i < s_column_define.size() ; i++ ){
                sheet.autoSizeColumn((short)i);
            }
        }

        if(student_sheet_name != null || teacher_sheet_name != null) {
            // 保存Excel文件
            try {
                OutputStream outputStream = new FileOutputStream(export_path);
                System.out.println("文件导出路径：" + export_path);
                workbook.write(outputStream);
                outputStream.close();
                return 1;
            } catch (Exception e) {
                e.printStackTrace();
                return -1;
            }
        }

        return 0; // 什么都没有做
    }

    /**
     * @Author Maple.Chen
     * @Description 师生信息导入模板下载，直接对接客户端响应
     * @Date 10:22 2021/3/16
     **/
    public static void ExportExcelTemplate_XLS_new(String template_name,/*模板名称*/
                                              String teacher_sheet_name,/*教师模板sheet页名称*/
                                              String teacher_title,/*教师模板sheet页中首行标题*/
                                              List<String> t_column_define, /*教师模板列定义*/
                                              List<Map<String, Object>> t_list_data, /*职工数据*/
                                              Map<String, String> t_dict_map,
                                                  String student_sheet_name,/*学生模板sheet页名称*/
                                              String student_title,/*学生模板sheet页中首行标题*/
                                              List<String> s_column_define, /*学生模板列定义*/
                                              List<Map<String, Object>> s_list_data, /*学生数据*/
                                              Map<String, String> s_dict_map,
                                                  String export_path /*文件导出路径*/,
                                                  HttpServletResponse response){

        // 第一步：创建一个工作簿对象
        HSSFWorkbook workbook = new HSSFWorkbook();

        if(teacher_sheet_name != null){
            // 第二步：添加Sheet页
            HSSFSheet sheet = workbook.createSheet(teacher_sheet_name);

            // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制
            HSSFRow row = sheet.createRow(0);

            // 第四步，创建风格（4.1和4.2两种风格）
            // 4.1 仅文字居中
            HSSFCellStyle style = workbook.createCellStyle();
            style.setAlignment(HorizontalAlignment.CENTER);
            // 4.2 单元格边框+居中
            CellStyle style2 = workbook.createCellStyle();
            style2.setBorderBottom(BorderStyle.THIN);
            style2.setBorderLeft(BorderStyle.THIN);
            style2.setBorderRight(BorderStyle.THIN);
            style2.setBorderTop(BorderStyle.THIN);
            style2.setAlignment(HorizontalAlignment.CENTER);
            HSSFFont font = workbook.createFont();
            font.setFontHeightInPoints((short) 10); //字体高度
            font.setColor(HSSFFont.COLOR_NORMAL); //字体颜色
            font.setFontName("宋体"); //字体
            style2.setFont(font);

            // 声明列对象
            HSSFCell cell = null;

            // 五：合并单元格并设置标题   [以最左上角单元格坐标(0,0)为基准]
            CellRangeAddress callRangeAddress = new CellRangeAddress(0,0,0,t_column_define.size() - 1);//起始行,结束行,起始列,结束列
            sheet.addMergedRegion(callRangeAddress);
            cell = row.createCell(0);
            cell.setCellValue(teacher_title);
            cell.setCellStyle(style);

            // 陆：设置列名 ---- “每创建一行都需要声明sheet.createRow(rowNum)”
            row = sheet.createRow(1);
            for( int i = 0; i < t_column_define.size() ; i++ ){
                cell = row.createCell(i);
                cell.setCellValue(t_dict_map.get(t_column_define.get(i)));
                cell.setCellStyle(style2);
            }

            // 第七布：设置合并单元格的边框（合并单元格属特殊情况），上下左右都要设置
            RegionUtil.setBorderTop(BorderStyle.THIN, callRangeAddress, sheet);
            RegionUtil.setBorderBottom(BorderStyle.THIN, callRangeAddress, sheet);
            RegionUtil.setBorderLeft(BorderStyle.THIN, callRangeAddress, sheet);
            RegionUtil.setBorderRight(BorderStyle.THIN, callRangeAddress, sheet);

            // 第八步：填充数据
            for(int i = 0; i < t_list_data.size(); i++){
                row = sheet.createRow(i + 2);
                for( int j = 0; j < t_column_define.size() ; j++ ){
                    cell = row.createCell(j);
                    cell.setCellValue((String)t_list_data.get(i).get(t_column_define.get(j)));
                    cell.setCellStyle(style);
                }
            }
            // 调整列宽度
            for( int i = 0; i < t_column_define.size() ; i++ ){
                sheet.autoSizeColumn((short)i);
            }
        }
        if(student_sheet_name != null){
            // 第二步：添加Sheet页
            HSSFSheet sheet = workbook.createSheet(student_sheet_name);

            // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制
            HSSFRow row = sheet.createRow(0);

            // 第四步，创建风格（4.1和4.2两种风格）
            // 4.1 仅文字居中
            HSSFCellStyle style = workbook.createCellStyle();
            style.setAlignment(HorizontalAlignment.CENTER);
            // 4.2 单元格边框+居中
            CellStyle style2 = workbook.createCellStyle();
            style2.setBorderBottom(BorderStyle.THIN);
            style2.setBorderLeft(BorderStyle.THIN);
            style2.setBorderRight(BorderStyle.THIN);
            style2.setBorderTop(BorderStyle.THIN);
            style2.setAlignment(HorizontalAlignment.CENTER);
            HSSFFont font = workbook.createFont();
            font.setFontHeightInPoints((short) 10); //字体高度
            font.setColor(HSSFFont.COLOR_NORMAL); //字体颜色
            font.setFontName("宋体"); //字体
            style2.setFont(font);

            // 声明列对象
            HSSFCell cell = null;

            // 五：合并单元格并设置标题   [以最左上角单元格坐标(0,0)为基准]
            CellRangeAddress callRangeAddress = new CellRangeAddress(0,0,0,s_column_define.size() - 1);//起始行,结束行,起始列,结束列
            sheet.addMergedRegion(callRangeAddress);
            cell = row.createCell(0);
            cell.setCellValue(student_title);
            cell.setCellStyle(style);

            // 陆：设置列名 ---- “每创建一行都需要声明sheet.createRow(rowNum)”
            row = sheet.createRow(1);
            for( int i = 0; i < s_column_define.size() ; i++ ){
                cell = row.createCell(i);
                cell.setCellValue(s_dict_map.get(s_column_define.get(i)));
                cell.setCellStyle(style2);
            }

            // 第七布：设置合并单元格的边框（合并单元格属特殊情况），上下左右都要设置
            RegionUtil.setBorderTop(BorderStyle.THIN, callRangeAddress, sheet);
            RegionUtil.setBorderBottom(BorderStyle.THIN, callRangeAddress, sheet);
            RegionUtil.setBorderLeft(BorderStyle.THIN, callRangeAddress, sheet);
            RegionUtil.setBorderRight(BorderStyle.THIN, callRangeAddress, sheet);

            // 第八步：填充数据
            for(int i = 0; i < s_list_data.size(); i++){
                row = sheet.createRow(i + 2);
                for( int j = 0; j < s_column_define.size() ; j++ ){
                    cell = row.createCell(j);
                    cell.setCellValue((String)s_list_data.get(i).get(s_column_define.get(j)));
                    cell.setCellStyle(style);
                }
            }
            // 调整列宽度
            for( int i = 0; i < s_column_define.size() ; i++ ){
                sheet.autoSizeColumn((short)i);
            }
        }

        if(student_sheet_name != null || teacher_sheet_name != null) {
            // 保存Excel文件
            try {
                OutputStream outputStream = response.getOutputStream();
                workbook.write(outputStream);
                outputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 读取模板时：对表格中数值进行格式化
     * @param cell
     * @return
     */
    public static Object getCellValue(Cell cell) {
        Object value = null;
        DecimalFormat df = new DecimalFormat("0"); // 格式化数字number String字符
        SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd"); // 日期格式化

        switch (cell.getCellTypeEnum()) {
            case STRING:
                value = cell.getRichStringCellValue().getString();
                break;
            case NUMERIC:
                if ("General".equals(cell.getCellStyle().getDataFormatString())) {
                    value = df.format(cell.getNumericCellValue());
                } else if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    Date date = cell.getDateCellValue();
                    value = DateFormatUtils.format(date, "yyyy-MM-dd");
                } else if ("m/d/yy".equals(cell.getCellStyle().getDataFormatString())) {
                    value = sdf.format(cell.getDateCellValue());
                } else if ( Double.toString(cell.getNumericCellValue()).contains(".") ){
                    value = Double.toString(cell.getNumericCellValue());
                } else {
                    // Default
                    value = df.format(cell.getNumericCellValue());
                }
                break;
            case BOOLEAN:
                value = cell.getBooleanCellValue();
                break;
            case BLANK:
                value = "";
                break;
            default:
                break;
        }

        return value;
    }

    /**
     * 判断某行是否是空行
     */
    public static boolean isRowEmpty(Row row) {
        if( row == null )
            return true;
        for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++){
            Cell cell = row.getCell(c);
            if ( cell != null || cell.getCellType() != CellType.BLANK || !StringUtils.isEmpty(cell + "") )
                return false;
        }
        return true;
    }

}
